package com.qys.livesMall.financial.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qys.livesMall.app.user.mapper.H2AppUserMapper;
import com.qys.livesMall.app.user.model.entity.H2AppUser;
import com.qys.livesMall.app.user.service.AppUserLevelService;
import com.qys.livesMall.common.exception.QysException;
import com.qys.livesMall.common.result.R;
import com.qys.livesMall.common.utils.DateUtils;
import com.qys.livesMall.finance.enums.AccountBusinessTypeEnum;
import com.qys.livesMall.finance.util.BusinessNoUtil;
import com.qys.livesMall.financial.mapper.FinancialOnlineMapper;
import com.qys.livesMall.financial.model.dto.app.AppFinancialOnlineDetailPageDTO;
import com.qys.livesMall.financial.model.dto.app.FinancialOnlineContractDTO;
import com.qys.livesMall.financial.model.dto.sys.FinancialOnlineRecordPageDTO;
import com.qys.livesMall.financial.model.entity.FinancialOnline;
import com.qys.livesMall.financial.model.entity.FinancialOnlineDetail;
import com.qys.livesMall.financial.mapper.FinancialOnlineDetailMapper;
import com.qys.livesMall.financial.model.vo.FinancialOnlineRecordVO;
import com.qys.livesMall.financial.model.vo.app.AppFinancialOnlineDetailPageVO;
import com.qys.livesMall.financial.model.vo.sys.FinancialOnlinePageVO;
import com.qys.livesMall.financial.service.FinancialOnlineDetailService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qys.livesMall.framework.utils.SecurityUtils;
import com.qys.livesMall.system.service.H2TemplateService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author
 * @since 2023-06-13
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class FinancialOnlineDetailServiceImpl extends ServiceImpl<FinancialOnlineDetailMapper, FinancialOnlineDetail> implements FinancialOnlineDetailService {

    private final FinancialOnlineMapper financialOnlineMapper;
    private final H2AppUserMapper userMapper;
    private final H2TemplateService templateService;

    @Override
    public Page<FinancialOnlineRecordVO> pageBySys(FinancialOnlineRecordPageDTO pageDTO) {
        Page<FinancialOnlineRecordVO> page = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        page=baseMapper.listBySysPage(page, pageDTO);
        return page;
    }

    @Override
    public FinancialOnlineDetail init(FinancialOnline onlineFinancial, Long userId, BigDecimal maxAmount, String contract) {
        FinancialOnlineDetail record = new FinancialOnlineDetail();
        record.setUserId(userId);
        record.setOnlineFinancialId(onlineFinancial.getId());
        record.setAmount(maxAmount);
        record.setUserName(SecurityUtils.getUsername());
        record.setInterestRate(onlineFinancial.getInterestRate());
        record.setPeriod(onlineFinancial.getPeriod());
        record.setStatus((byte) 1);
        LocalDateTime nextStartTheDay = DateUtils.startOfTheDay().plusDays(1);
        record.setStartTime(nextStartTheDay);
        record.setEndTime(nextStartTheDay.plusDays(onlineFinancial.getPeriod()-1));
        record.setContract(contract);
        record.setCreateTime(LocalDateTime.now());
        record.setReturnPrincipalTime(record.getSettlementTime());
        record.setReturnPrincipalStatus((byte) 2);
        record.setOrderNo(BusinessNoUtil.get(AccountBusinessTypeEnum.PRODUCT_INVESTMENT));
        save(record);
        return record;
    }

    @Override
    public Page<AppFinancialOnlineDetailPageVO> pageByApp(AppFinancialOnlineDetailPageDTO pageDTO) {
        Page<AppFinancialOnlineDetailPageVO> page = new Page<>(pageDTO.getPageNum(), pageDTO.getPageSize());
        page=baseMapper.listByAppPage(page, pageDTO);
        return page;
    }

    @Override
    public FinancialOnlineContractDTO buildContract(FinancialOnlineContractDTO cc) {
        FinancialOnline onlineFinancial=financialOnlineMapper.selectById(cc.getFinancialId());
        if (onlineFinancial==null){
            throw new QysException("请检查理财产品ID");
        }
        H2AppUser user = userMapper.selectById(SecurityUtils.getUserId());
        return buildContract(user,onlineFinancial,cc);
    }

    @Override
    public String getBuyContract(Long id) {
        FinancialOnlineDetail financialOnlineDetail=getById(id);
        return financialOnlineDetail.getContract();
    }

    @Override
    public List<FinancialOnlineDetail> getYesterday() {
        return baseMapper.getYesterday();
    }

    private FinancialOnlineContractDTO buildContract(H2AppUser user, FinancialOnline onlineFinancial, FinancialOnlineContractDTO cc){
        String template=templateService.getByCode(onlineFinancial.getContractTemplateCode());
        if (StringUtils.isBlank(template)){
            return null;
        }
        Map<String,Object> params=getParam(user,onlineFinancial,cc);

        ExpressionParser parser = new SpelExpressionParser();
        TemplateParserContext parserContext = new TemplateParserContext();
        String contract = parser.parseExpression(template,parserContext).getValue(params, String.class);
        cc.setCode(params.get("contractCode").toString());
        cc.setContract(contract);
        return cc;
    }


    private Map<String,Object> getParam(H2AppUser user,FinancialOnline onlineFinancial,FinancialOnlineContractDTO cc){
        Map<String, Object> params = new HashMap<>();
        params.put("userName", user.getUserName());
        params.put("mobile", user.getMobile());
        params.put("contractCode", System.currentTimeMillis());
        params.put("financialId", onlineFinancial.getId());
        params.put("financialName", onlineFinancial.getName());
        params.put("interestRate", onlineFinancial.getInterestRate());
        params.put("period", onlineFinancial.getPeriod());
        params.put("purchaseNum", cc.getPurchaseNum());
        params.put("unitPrice", cc.getUnitPrice());
        params.put("totalPrice", cc.getTotalPrice());
        params.put("createTime", DateUtils.dateNow());
        return params;

    }


}
